package com.kreao.korean.security;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import javax.crypto.SecretKey;
import java.util.Date;

@Slf4j
@Component
public class JwtUtils {
    
    @Value("${jwt.secret}")
    private String jwtSecret;
    
    @Value("${jwt.expiration}")
    private int jwtExpirationMs;
    
    @PostConstruct
    public void init() {
        log.info("Initializing JwtUtils...");
        
        // Handle encrypted vs plain text secrets
        if (jwtSecret == null || jwtSecret.trim().isEmpty()) {
            log.warn("JWT secret is not configured, using default fallback");
            jwtSecret = "korean-learning-default-jwt-secret-key-for-development-only-2023";
        }
        
        // Check if the secret is too short for HMAC-SHA512
        if (jwtSecret.getBytes().length < 64) {
            log.warn("JWT secret is shorter than recommended 64 bytes, padding it");
            jwtSecret = jwtSecret + "-padded-to-meet-minimum-length-requirements-for-hmac-sha512";
        }
        
        log.info("JWT secret length: {} bytes", jwtSecret.getBytes().length);
        
        // Test secret key creation
        try {
            getSigningKey();
            log.info("JWT configuration validated successfully");
        } catch (Exception e) {
            log.error("JWT configuration validation failed: {}", e.getMessage());
            throw new IllegalStateException("Invalid JWT configuration", e);
        }
    }
    
    private SecretKey getSigningKey() {
        try {
            if (jwtSecret == null || jwtSecret.trim().isEmpty()) {
                throw new IllegalStateException("JWT secret is not configured properly");
            }
            return Keys.hmacShaKeyFor(jwtSecret.getBytes());
        } catch (Exception e) {
            log.error("Failed to create signing key: {}", e.getMessage());
            throw new IllegalStateException("JWT configuration error", e);
        }
    }
    
    public String generateJwtToken(Authentication authentication) {
        UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
        
        return Jwts.builder()
                .setSubject(userPrincipal.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(new Date().getTime() + jwtExpirationMs))
                .signWith(getSigningKey(), SignatureAlgorithm.HS512)
                .compact();
    }
    
    public String generateTokenFromUsername(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(new Date().getTime() + jwtExpirationMs))
                .signWith(getSigningKey(), SignatureAlgorithm.HS512)
                .compact();
    }
    
    public String getUserNameFromJwtToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
    
    public boolean validateJwtToken(String authToken) {
        try {
            Jwts.parserBuilder()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(authToken);
            return true;
        } catch (MalformedJwtException e) {
            log.error("Invalid JWT token: {}", e.getMessage());
        } catch (ExpiredJwtException e) {
            log.error("JWT token is expired: {}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            log.error("JWT token is unsupported: {}", e.getMessage());
        } catch (IllegalArgumentException e) {
            log.error("JWT claims string is empty: {}", e.getMessage());
        }
        
        return false;
    }
} 